// 公共方法

module.exports = {
  version: "last update：2020.05.12 , veriosn：1.0.0",
  /*new start*/

  /**
   *
   * JS获取时间(今天，昨天，近一周，近一个月等) start
   * @param dateNow :Date类
   * @param intervalDays ：间隔天数
   * @param bolPastTime  ：Boolean,判断在参数date之前，还是之后，
   */
  // 原文链接：https://blog.csdn.net/qq_41090476/article/details/96133830
  getDateRange(dateNow,intervalDays,bolPastTime){
  let oneDayTime = 24 * 60 * 60 * 1000;
  let list = [];
  let lastDay;

  if(bolPastTime == true){
    lastDay = new Date(dateNow.getTime() - intervalDays * oneDayTime);
    list.push(this.formateDate(lastDay));
    list.push(this.formateDate(dateNow));
  }else{
    lastDay = new Date(dateNow.getTime() + intervalDays * oneDayTime);
    list.push(this.formateDate(dateNow));
    list.push(this.formateDate(lastDay));
  }
  return list;
},
 formateDate(time){
  let year = time.getFullYear()
  let month = time.getMonth() + 1
  let day = time.getDate()

  if (month < 10) {
    month = '0' + month
  }

  if (day < 10) {
    day = '0' + day
  }

  return year + '-' + month + '-' + day + ''

},

  /*JS获取时间(今天，昨天，近一周，近一个月等)_ end*/


// 封装去重的方法 maxArr 长度大的数组   minArr 长度小的数组,要进行比较的数组  返回的结果
  arrRemoveRepetition(maxArr, minArr) {
  var nArr = [];  //存储新数组
  nArr = maxArr.filter(function(item) {
    var temp = minArr.map(function(v) {
      return v.id
    })
    return !temp.includes(item.id)
  })
  return nArr
},
  getArrDifference(arr1, arr2) {

    return arr1.concat(arr2).filter(function(v, i, arr) {

      return arr.indexOf(v) === arr.lastIndexOf(v);

    });

  },
  getArrEqual(arr1, arr2) {
    let newArr = [];
    for (let i = 0; i < arr2.length; i++) {
      for (let j = 0; j < arr1.length; j++) {
        if(arr1[j].id != arr2[i].id){
          newArr.push(arr1[j]);
        }
      }
    }
    return newArr;
  },
  // 封装去重的方法 maxArr 长度大的数组   minArr 长度小的数组,要进行比较的数组  返回的结果
  csMethod(maxArr, minArr) {
    var nArr = [];  //存储新数组
    nArr = maxArr.filter(function(item) {
      var temp = minArr.map(function(v) {
        return v.id
      })
      return temp.includes(item.id)
    })
    return nArr
  },

  mergeArrays (arr1, arr2) {
    let res = [];
    res = arr1.map(obj => {
      const index = arr2.findIndex(el => el["id"] == obj["id"]);
      const { address } = index !== -1 ? arr2[index] : {};
      return {
        ...obj,
        address
      };
    });
    return res;
  },

  diff(arr1, arr2) {
  var arr3 =[];
  for (key in arr1) {
    var stra = arr1[key].id;
    var count = 0;
    for(var j= 0; j < arr2.length; j++){
      var strb = arr2[j].id;
      if(stra == strb) {
        count++;
      }
    }
    if(count===0) {//表示数组1的这个值没有重复的，放到arr3列表中
      arr3.push(stra);
    }
  }
  for (key in arr2) {
    var stra = arr2[key];
    var count = 0;
    for(var j= 0; j < arr1.length; j++){
      var strb = arr1[j];
      if(stra == strb) {
        count++;
      }
    }
    if(count===0) {//表示数组1的这个值没有重复的，放到arr3列表中
      arr3.push(stra);
    }
  }

  return arr3;

},


//时间排序
//prop：对象数组排序的键，
//align：排序方式，"positive"正序，"inverted"倒序。
  compare(prop,align){
  return function(a,b){
    var value1=a[prop];
    var value2=b[prop];
    if(align=="positive"){//正序
      return new Date(value1)-new Date(value2);
    }else if(align=="inverted"){//倒序
      return new Date(value2)-new Date(value1);
    }
  }
},

 // 秒级时间戳  转 日期格式
 timestampToTime(timestamp) {
  /*时间戳为10位需*1000，时间戳为13位不需乘1000
  var date = new Date(timestamp * 1000);*/
  var date = new Date(timestamp);
  var Y = date.getFullYear() + "-";
  var M =
    (date.getMonth() + 1 < 10
      ? "0" + (date.getMonth() + 1)
      : date.getMonth() + 1) + "-";
  var D = (date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + " ";
  var h = date.getHours() + ":";
  var m = date.getMinutes() + ":";
  var s = date.getSeconds();
  return Y + M + D + h + m + s;
},

//JS使用正则表达式校验电话号码
  checkModbile(mobile) {
    // var re = /^(0|86|17951)?(1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$/;
    var re = /^1[3,4,5,6,7,8,9][0-9]{9}$/;
    var result = re.test(mobile);
    if(!result) {
      return false;//若手机号码格式不正确则返回false
    }
    return true;
  },

  checkEmail(email) {
    var re = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/;
    var result = re.test(email);
    if(!result) {
      return false;//若手机号码格式不正确则返回false
    }
    return true;
  },
  /*checkModbile(mobile){
    const regMobile =
      /^(0|86|17951)?(1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$/
    if (regEmail.test(value)) {
      // 合法邮箱
      return cb()
    }
  },*/



// 在指定数组中取出N个不重复的数据
  // 从一个给定的数组arr中，随机返回num个不重复项
  randomNum(arr,num){
    // 新建一个数组，将传入的数组复制，用于运算，而不要直接操作传入的数据
    var temp = new Array();
    for (var i in arr){
      temp.push(arr[i])
    }
    // 取出的数据项，保存在此数组
    var newArray=new Array();
    for(var j=0;j<num;j++){
      console.log("num=======",num)
      // 判断如果数组还有可以取出的元素，以防下标越界
      if(temp.length>0){
        // 在数组中产生一个随机索引
        var arrIndex=Math.floor(Math.random()*temp.length);
        console.log("arrIndex",arrIndex)
        // 将此随机索引的对应的数组元素值push进数组
        newArray.push(temp[arrIndex]);
        //然后删掉次索引的数组元素，这时候temp变为新的数组
        temp.splice(arrIndex,1)
      }
      else{
        // 数组中数据项取完后，退出循环，比如数组本来只有10项，单要求去除20项
        break
      }
    }
    return newArray
  },

  //获取明天的时间
  tomorrow(){
    var date = new Date();
    date.setTime(date.getTime()+24*60*60*1000);
    var year = date.getFullYear();
    var month = date.getMonth() + 1 >=10 ? date.getMonth() + 1 : '0' + (date.getMonth() + 1);
    var day = date.getDate() < 10 ? '0'+(date.getDate()) : date.getDate();
    let tomorrow = year + "-" + month  + "-" + day;
    return tomorrow
  },

  // 获取后N天日期
  getLastOrNextFewDateBy (now,publishDays) {
    // now：随机开始时间; publishDays：发布天数
    console.log("now----",now)
    var year = now.getFullYear(); //得到年份
    var month = now.getMonth()+1;//得到月份
    var day = now.getDate()//得到日期
    var date = now.getDate();//得到日期
    date = year + "年" + month + "月" + date + "日" ;
    console.log('date222========',date)
    // let dayNum= Number(publishDays)+1   // 在发布天数+1
    let dayNum= Number(publishDays)
    let resultList=[]
    let sameDay = year + "-" + month  + "-" + day;
    resultList.push(sameDay)
    for (let i = 1; i < dayNum; i++) {
      //24 * 3600 * 1000 就是计算一天的时间
      var date = new Date(now.getTime() + i * 24 * 3600 * 1000);
      var year = date.getFullYear();
      var month = date.getMonth() + 1 >=10 ? date.getMonth() + 1 : '0' + (date.getMonth() + 1);
      var day = date.getDate() < 10 ? '0'+(date.getDate()) : date.getDate();
      /*
      var dt2 = new Date(now.getTime() + i * 24 * 3600 * 1000);
      var weekDay = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
      var weekDays = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];*/
      //把七天的时间和星期添加到数组中
      let result = year + "-" + month  + "-" + day;
      resultList.push(result);
      /*check.push({
        date:result,
        day: day,
        weekday: weekDays[dt2.getDay()],
        week: weekDay[dt2.getDay()],
      });*/
    }
    console.log('获取后N天日期resultList-============',resultList);
    return resultList
  },


  // 时间转换
  timeForMat(count) {
    // 拼接时间
    const time1 = new Date()

    if (count === 1) {
      time1.setTime(time1.getTime() - (24 * 60 * 60 * 1000))
    } else {
      if (count >= 0) {
        time1.setTime(time1.getTime())
      } else {
        if (count === -2) {
          time1.setTime(time1.getTime() + (24 * 60 * 60 * 1000) * 2)
        } else {
          time1.setTime(time1.getTime() + (24 * 60 * 60 * 1000))
        }
      }
    }

    const Y1 = time1.getFullYear()
    const M1 = ((time1.getMonth() + 1) > 9 ? (time1.getMonth() + 1) : '0' + (time1.getMonth() + 1))
    const D1 = (time1.getDate() > 9 ? time1.getDate() : '0' + time1.getDate())
    // const timer1 =M1 + '-' + D1 // 当前时间
    var date =[];
    // date.push(timer1);
    for(var i=1;i<=count;i++){
      const time2 = new Date()
      time2.setTime(time2.getTime() + (24 * 60 * 60 * 1000 * i))
      const Y2 = time2.getFullYear()
      const M2 = ((time2.getMonth() + 1) > 9 ? (time2.getMonth() + 1) : '0' + (time2.getMonth() + 1))
      const D2 = (time2.getDate() > 9 ? time2.getDate() : '0' + time2.getDate())
      const yesterday = Y2 + '-' + M2 + '-' + D2  // 之后的7天的日期
      date.push(yesterday);
    }
    return date;
  },


  //js 中国标准时间转化为年月日
  msToDate (datetime) {
    console.log('datetime',datetime)
    let year = datetime.getFullYear();
    let month = datetime.getMonth();
    let date = datetime.getDate();
    let result = year + '-' + ((month + 1) >= 10 ? (month + 1) : '0' + (month + 1)) + '-' + ((date + 1) < 10 ? '0' + date : date);
    return result;
  },

  /*end*/


  /*判断一个元素是否在数组中*/
  contains(arr, val) {
    return arr.indexOf(val) != -1 ? true : false;
  },

  // 查找数组最小值
  arrayMin(arr) {
    return Math.min(...arr);
  },
  // 从数组中移除 falsey 值
  arrayCompact(arr) {
    return arr.filter(Boolean);
  },

  // 数组中重复的值计数
  arrCount(arr, value) {
    return arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0);
  },
  // 返回两个数组差异
  arrayDiff(a, b) {
    const s = new Set(b);
    return a.filter(x => !s.has(x));
  },
  // 判断数组元素是否重复
  isArrRepeat(arr) {
    let _arr = arr.sort();
    console.log(_arr);
    for (let i = 0; i < _arr.length; i++) {
      if (_arr[i] === _arr[i + 1]) {
        return true;
      }
    }
    return false;
  },

  /**
   * @param  {arr} 数组
   * @param  {fn} 回调函数
   * @return {undefined}
   */
  each(arr, fn) {
    fn = fn || Function;
    let a = [];
    let args = Array.prototype.slice.call(arguments, 1);
    for (let i = 0; i < arr.length; i++) {
      let res = fn.apply(arr, [arr[i], i].concat(args));
      if (res != null) a.push(res);
    }
  },

  /**
   * @param  {arr} 数组
   * @param  {fn} 回调函数
   * @param  {thisObj} this指向
   * @return {Array}
   */
  map(arr, fn, thisObj) {
    let scope = thisObj || window;
    let a = [];
    for (let i = 0, j = arr.length; i < j; ++i) {
      let res = fn.call(scope, arr[i], i, this);
      if (res != null) a.push(res);
    }
    return a;
  },


  /**
   * @param  {arr} 数组
   * @param  {type} 1：从小到大   2：从大到小   3：随机
   * @return {Array}
   */
  sort(arr, type = 1) {
    return arr.sort((a, b) => {
      switch (type) {
        case 1:
          return a - b;
        case 2:
          return b - a;
        case 3:
          return Math.random() - 0.5;
        default:
          return arr;
      }
    })
  },

  /*去重*/
  arrayUnique(arr) {
    if (Array.hasOwnProperty('from')) {
      return Array.from(new Set(arr));
    } else {
      let n = {},
        r = [];
      for (let i = 0; i < arr.length; i++) {
        if (!n[arr[i]]) {
          n[arr[i]] = true;
          r.push(arr[i]);
        }
      }
      return r;
    }
    // 注：上面 else 里面的排重并不能区分 2 和 '2'，但能减少用indexOf带来的性能
    /* 正确排重
    if ( Array.hasOwnProperty('from') ) {
        return Array.from(new Set(arr))
    }else{
        let r = [], NaNBol = true
        for(let i=0; i < arr.length; i++) {
            if (arr[i] !== arr[i]) {
                if (NaNBol && r.indexOf(arr[i]) === -1) {
                    r.push(arr[i])
                    NaNBol = false
                }
            }else{
                if(r.indexOf(arr[i]) === -1) r.push(arr[i])
            }
        }
        return r
    }
     */
  },

  /*求两个集合的并集*/
  union(a, b) {
    let newArr = a.concat(b);
    return this.arrayUnique(newArr);
  },

  /*求两个集合的交集*/
  intersect(a, b) {
    let _this = this;
    a = this.arrayUnique(a);
    return this.map(a, function(o) {
      return _this.contains(b, o) ? o : null;
    });
  },

  /*删除其中一个元素*/
  arrayRemove(arr, ele) {
    let index = arr.indexOf(ele);
    if (index > -1) {
      arr.splice(index, 1);
    }
    return arr;
  },

  /*删除某一项数组*/
  arraySplice(arr, index) {
    arr.splice(Number(index), 1);
    return arr;
  },

  /*将类数组转换为数组的方法*/
  formArray(ary) {
    let arr = [];
    if (Array.isArray(ary)) {
      arr = ary;
    } else {
      arr = Array.prototype.slice.call(ary);
    };
    return arr;
  },

  /*最大值*/
  max(arr) {
    return Math.max.apply(null, arr);
  },

  /*最小值*/
  min(arr) {
    return Math.min.apply(null, arr);
  },

  /*求和*/
  sum(arr) {
    return arr.reduce((pre, cur) => {
      return pre + cur
    });
  },

  /*平均值*/
  average(arr) {
    return this.sum(arr) / arr.length;
  },


  /**
   * 转义要在正则表达式中使用的字符串(特殊字符)
   * @param {String} str '(test)'
   * @return {RegExp} "\(test\)"
   * */
  escapeRegExp(str) {
    return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  },
  /**
   * @param {String} hex '#f00'
   * @return {String} 'rgba(xx,xx,xx)'
   * @example toHex('#f00')
   * */
  toRgba(hex) {
    const extendHex = shortHex =>
      '#' + shortHex.slice(shortHex.startsWith('#') ? 1 : 0).split('').map(x => x + x).join('');
    const extendedHex = hex.slice(hex.startsWith('#') ? 1 : 0).length === 3 ? extendHex(hex) : hex;
    return `rgb(${parseInt(extendedHex.slice(1), 16) >> 16}, ${(parseInt(extendedHex.slice(1), 16) & 0x00ff00) >> 8}, ${parseInt(extendedHex.slice(1), 16) & 0x0000ff})`;
  },


  /**
   * @param {Number} r
   * @param {Number} g
   * @param {Number} b
   * @return {String} '#000'
   * @example toHex(0,0,0)
   * */
  toHex(r, g, b) {
    return '#' + ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');
  },

  /**
   * 设置和获取同步缓存
   * @param {String} key 设置key
   * @param {Any} value 缓存任意值
   * @return {Any} 返回版本信息
   */
  setCache(key, value) {
    wx.setStorageSync(key, JSON.stringify(value));
  },

  getCache(key) {
    try {
      return JSON.parse(wx.getStorageSync(key));
    } catch (e) {
      //TODO handle the exception
      return wx.getStorageSync(key);
    }
  },

  removeCache(key) {
    wx.removeStorageSync(key);
  },

  clearCache() {
    wx.clearStorageSync();
  },
  dateDayDiff(dateInitial, dateFinal) {
    return (dateFinal - dateInitial) / (1000 * 3600 * 24)
  },
  // 获取是否闰年
  dateLeapYear() {
    let year = new Date().getFullYear();
    return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
  },

  // 获取当前时间戳 - 13位转为10位，然后*1000再parseInt
  dateStamp(digits = 10) {
    digits = Number(digits);
    switch (digits) {
      case 10:
        return Math.round(new Date().getTime() / 1000).toString();
      case 13:
        return new Date().getTime().toString();
    }
  },
  /**
   * 类型判断
   * @param {String,Number} number 传入的数值
   * @return {String} 返回字符串
   */
  toDigit(any) {
    return any.toString().replace(/^(\d)$/, `0$1`);
  },

  /**
   *秒转成分钟： 如 100 => 01:40
   *
   * @param {*} sec
   * @returns
   */
  dateStoM(sec) {
    const MINUTE = 60;
    const minute = Math.floor(sec / MINUTE);
    const surplusSec = sec % MINUTE;
    return `${this.toDigit(minute)}:${this.toDigit(surplusSec)}`;
  },


  /**
   * 传入13位时间戳获取距离当前时间
   * @param {*} sec
   * @return {String} 3天前 返回距离时间具体描述
   */
  dateDistance(timestamp) {
    let publishTime = Number(timestamp) / 1000,
      date = new Date(publishTime * 1000),
      Y = this.toDigit(date.getFullYear()),
      M = this.toDigit(date.getMonth() + 1),
      D = this.toDigit(date.getDate()),
      H = this.toDigit(date.getHours()),
      m = this.toDigit(date.getMinutes()),
      s = this.toDigit(date.getSeconds());
    let nowTime = new Date().getTime() / 1000,
      diffValue = nowTime - publishTime,
      diff_days = parseInt(diffValue / 86400),
      diff_hours = parseInt(diffValue / 3600),
      diff_minutes = parseInt(diffValue / 60),
      diff_secodes = parseInt(diffValue);

    if (diff_days > 0 && diff_days < 3) {
      return diff_days + "天前";
    } else if (diff_days <= 0 && diff_hours > 0) {
      return diff_hours + "小时前";
    } else if (diff_hours <= 0 && diff_minutes > 0) {
      return diff_minutes + "分钟前";
    } else if (diff_secodes < 60) {
      if (diff_secodes <= 0) {
        return "刚刚";
      } else {
        return diff_secodes + "秒前";
      }
    } else if (diff_days >= 3 && diff_days < 30) {
      return M + '-' + D + ' ' + H + ':' + m;
    } else if (diff_days >= 30) {
      return Y + '-' + M + '-' + D + ' ' + H + ':' + m;
    }
  },
  /**
   * 获取当天周几
   * @param {}
   * @return {String} "星期x" 返回周几
   */
  dateWeek() {
    let day = new Date().getDay();
    let week = new Array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五");
    return week[day];
  },
  /**
   * 获取当天是否周六周日
   * @param {}
   * @return {Boolean} true/false 返回是否周六周日
   */
  dateWeekend() {
    let _date = new Date();
    let _nowTime = _date.getTime();
    let _week = _date.getDay();
    let _yearMonthDay =
      `${_date.getFullYear()}-${_date.getMonth()+1>=10?_date.getMonth()+1:'0'+_date.getMonth()+1}-${_date.getDate()>=10?_date.getDate():'0'+_date.getDate()}`;
    let _dayLongTime = 24 * 60 * 60 * 1000;
    let _furtureSundayTimes = _nowTime + (7 - _week) * _dayLongTime;
    let _furtureSaturdayTimes = _nowTime + (6 - _week) * _dayLongTime;
    let _mealSunDay;
    let _mealSaturDay;
    _furtureSundayTimes = new Date(_furtureSundayTimes);
    _furtureSaturdayTimes = new Date(_furtureSaturdayTimes);
    let _satYear = _furtureSaturdayTimes.getFullYear();
    let _satMonth = _furtureSaturdayTimes.getMonth() + 1;
    let _satDay = _furtureSaturdayTimes.getDate();
    let _sunYear = _furtureSundayTimes.getFullYear();
    let _sunMonth = _furtureSundayTimes.getMonth() + 1;
    let _sunDay = _furtureSundayTimes.getDate();
    _satMonth = _satMonth >= 10 ? _satMonth : '0' + _satMonth;
    _satDay = _satDay >= 10 ? _satDay : '0' + _satDay;
    _sunMonth = _sunMonth >= 10 ? _sunMonth : '0' + _sunMonth;
    _sunDay = _sunDay >= 10 ? _sunDay : '0' + _sunDay;
    _mealSunDay = _satYear + '-' + _satMonth + '-' + _satDay;
    _mealSaturDay = _sunYear + '-' + _sunMonth + '-' + _sunDay;
    let _weekendDay = [_mealSunDay, _mealSaturDay];
    let _isWeekend = _weekendDay.indexOf(_yearMonthDay) != -1;
    // 最近的周六/周日 _weekendDay.  _isWeekend:true | false
    return _isWeekend;
  },
  /**
   * 传入具体日期返回13位时间戳
   * @param {String} date "2020/07/13 18:00"
   * @return {String} "1589257080657"
   */
  dateToStamp(stamp) {
    return new Date(stamp).getTime();
  },
  /**
   * 传入13位时间戳
   * @param {String,Number} timestamp "1589257080657"
   * @param {String} format "Y-M-D Y-M-D-h-m-s"
   * @return {String} "2020*01*05 10:00"
   */
  dateFormat(timestamp, format) {
    format = format || `Y-M-D`;
    const cur = Number(timestamp) ? new Date(Number(timestamp)) : new Date();
    const year = cur.getFullYear();
    const month = this.toDigit(cur.getMonth() + 1);
    const day = this.toDigit(cur.getDate());
    const hour = this.toDigit(cur.getHours());
    const minute = this.toDigit(cur.getMinutes());
    const second = this.toDigit(cur.getSeconds());
    return format.replace(/Y|M|D|h|m|s/g, function(matches) {
      return ({
        Y: year,
        M: month,
        D: day,
        h: hour,
        m: minute,
        s: second
      })[matches];
    });
  },

  /**
   * 格式化时间
   *
   * @param  {time} 时间
   * @param  {cFormat} 格式
   * @return {String} 字符串
   *
   * @example formatTime('2018-1-29', '{y}/{m}/{d} {h}:{i}:{s}') // -> 2018/01/29 00:00:00
   */
  formatTime(time, cFormat) {
    if (arguments.length === 0) return null
    if ((time + '').length === 10) {
      time = +time * 1000
    }

    let format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}',
      date
    if (typeof time === 'object') {
      date = time
    } else {
      date = new Date(time)
    }

    let formatObj = {
      y: date.getFullYear(),
      m: date.getMonth() + 1,
      d: date.getDate(),
      h: date.getHours(),
      i: date.getMinutes(),
      s: date.getSeconds(),
      a: date.getDay()
    }
    let time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
      let value = formatObj[key]
      if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
      if (result.length > 0 && value < 10) {
        value = '0' + value
      }
      return value || 0
    })
    return time_str
  },


  /**
   * 返回指定长度的月份集合
   *
   * @param  {time} 时间
   * @param  {len} 长度
   * @param  {direction} 方向：  1: 前几个月;  2: 后几个月;  3:前后几个月  默认 3
   * @return {Array} 数组
   *
   * @example   dateMonths('2018-1-29', 6, 1)  // ->  ["2018-1", "2017-12", "2017-11", "2017-10", "2017-9", "2017-8", "2017-7"]
   */
  dateMonths(time, len, direction) {
    direction = isNaN(direction) ? 3 : direction;
    let mm = new Date(time).getMonth() + 1,
      yy = new Date(time).getFullYear(),
      index = mm;

    let cutMonth = function(index) {
      let arr
      if (direction === 1) {
        arr = formatPre(index).reverse()
      } else if (direction === 2) {
        arr = formatNext(index)
      } else {
        arr = formatPre(index).reverse().slice(len / 2).concat(formatNext(index).slice(1, len / 2 + 1))
      }
      return arr.sort(function(t1, t2) {
        return new Date(t1).getTime() - new Date(t2).getTime()
      })
    }

    let formatPre = function(index) {
      let currNum = index,
        preNum = 0,
        currArr = [],
        preArr = []
      if (index - len < 0) {
        preNum = len - currNum
      }
      for (let i = 0; i < currNum; i++) {
        currArr.push([yy + '-' + (currNum - i)])
      }
      for (let i = 1; i <= preNum; i++) {
        preArr.push([(yy - Math.ceil(i / 12)) + '-' + (12 - (i - 1) % 12)])
      }
      return currArr.concat(preArr)
    }

    let formatNext = function(index) {
      let currNum = 12 - index,
        nextNum = 0,
        currArr = [],
        nextArr = []
      if (len - currNum > 0) {
        nextNum = len - currNum
      }
      for (let i = 0; i <= currNum; i++) {
        currArr.push([yy + '-' + (index + i)])
      }
      for (let i = 1; i < nextNum; i++) {
        nextArr.push([(yy + Math.ceil(i / 12)) + '-' + (i % 13 === 0 ? 1 : i % 13)])
      }
      return currArr.concat(nextArr)
    }
    return cutMonth(index)
  },



  /**
   * 返回指定长度的天数集合
   *
   * @param  {time} 时间
   * @param  {len} 长度
   * @param  {direction} 方向： 1: 前几天;  2: 后几天;  3:前后几天  默认 3
   * @return {Array} 数组
   *
   * @example dateDays('2018-1-29', 6) // -> ["2018-1-26", "2018-1-27", "2018-1-28", "2018-1-29", "2018-1-30", "2018-1-31", "2018-2-1"]
   */
  dateDays(time, len, diretion) {
    let tt = new Date(time)
    let getDay = function(day) {
      let t = new Date(time)
      t.setDate(t.getDate() + day)
      let m = t.getMonth() + 1
      return t.getFullYear() + '-' + m + '-' + t.getDate()
    }
    let arr = []
    if (diretion === 1) {
      for (let i = 1; i <= len; i++) {
        arr.unshift(getDay(-i))
      }
    } else if (diretion === 2) {
      for (let i = 1; i <= len; i++) {
        arr.push(getDay(i))
      }
    } else {
      for (let i = 1; i <= len; i++) {
        arr.unshift(getDay(-i))
      }
      arr.push(tt.getFullYear() + '-' + (tt.getMonth() + 1) + '-' + tt.getDate())
      for (let i = 1; i <= len; i++) {
        arr.push(getDay(i))
      }
    }
    return diretion === 1 ? arr.concat([tt.getFullYear() + '-' + (tt.getMonth() + 1) + '-' + tt.getDate()]) :
      diretion === 2 ? [tt.getFullYear() + '-' + (tt.getMonth() + 1) + '-' + tt.getDate()].concat(arr) : arr
  },


  /**
   * @param  {s} 秒数
   * @return {String} 字符串
   *
   * @example formatHMS(3610) // -> 1h0m10s
   */
  dateStoH(s) {
    let str = ''
    if (s > 3600) {
      str = Math.floor(s / 3600) + 'h' + Math.floor(s % 3600 / 60) + 'm' + s % 60 + 's'
    } else if (s > 60) {
      str = Math.floor(s / 60) + 'm' + s % 60 + 's'
    } else {
      str = s % 60 + 's'
    }
    return str
  },

  /*获取某月有多少天*/
  dateMonthOfDay(timestamp) {
    let date = new Date(Number(timestamp))
    let year = date.getFullYear()
    let mouth = date.getMonth() + 1
    let days

    //当月份为二月时，根据闰年还是非闰年判断天数
    if (mouth == 2) {
      days = (year % 4 == 0 && year % 100 == 0 && year % 400 == 0) || (year % 4 == 0 && year % 100 != 0) ?
        28 : 29
    } else if (mouth == 1 || mouth == 3 || mouth == 5 || mouth == 7 || mouth == 8 || mouth == 10 || mouth ==
      12) {
      //月份为：1,3,5,7,8,10,12 时，为大月.则天数为31；
      days = 31
    } else {
      //其他月份，天数为：30.
      days = 30
    }
    return days
  },

  /*获取某年有多少天*/
  dateYearOfDay(time) {
    let firstDayYear = this.dateFirstDayOfYear(time);
    let lastDayYear = this.dateLastDayOfYear(time);
    let numSecond = (new Date(lastDayYear).getTime() - new Date(firstDayYear).getTime()) / 1000;
    return Math.ceil(numSecond / (24 * 3600));
  },

  /*获取某年的第一天*/
  dateFirstDayOfYear(time) {
    let year = new Date(time).getFullYear();
    return year + "-01-01 00:00:00";
  },

  /*获取某年最后一天*/
  dateLastDayOfYear(time) {
    let year = new Date(time).getFullYear();
    let dateString = year + "-12-01 00:00:00";
    let endDay = this.getMonthOfDay(dateString);
    return year + "-12-" + endDay + " 23:59:59";
  },

  /*获取某个日期是当年中的第几天*/
  dateDayOfYear(time) {
    let firstDayYear = this.dateFirstDayOfYear(time);
    let numSecond = (new Date(time).getTime() - new Date(firstDayYear).getTime()) / 1000;
    return Math.ceil(numSecond / (24 * 3600));
  },

  /*获取某个日期在这一年的第几周*/
  dateDayOfYearWeek(time) {
    let numdays = this.dateDayOfYear(time);
    return Math.ceil(numdays / 7);
  },

  /**
   * 获取数据类型
   * @param {Any} any 任意类型
   * @return {Any} any
   *
   * @example getDataType(null)=>Null;
   * */
  getDataType(any) {
    let temp = Object.prototype.toString.call(any);
    let type = temp.replace(/\[/g, '').replace(/\]/g, '');
    let index = type.lastIndexOf(" ");
    let str = type.substring(index + 1, type.length);
    return str;
  },

  /**
   * 对象所有值是否为空
   * @param {Object} obj 传入对象
   * @return {Boolean} 返回true或false
   */
  isObjectValEmpty(object) {
    let isEmpty = true;
    Object.keys(object).forEach(function(x) {
      if (object[x] != null && object[x] != '') {
        isEmpty = false;
      }
    });
    if (isEmpty) {
      //值全为空
      return true;
    }
    return false;
  },

  /**
   * 是否对象
   * @param {Object} obj 传入对象
   * @return {Boolean} 返回true或false
   */
  isObject(obj) {
    return obj !== null && typeof obj === 'object';
  },


  /**
   * 是否正则表达式
   * @param {RegExp} v 传入正则表达式
   * @return {Boolean} 返回true或false
   */
  isRegExp(v) {
    return Object.prototype.toString.call(v) === '[object RegExp]';
  },

  /**
   * 是否未定义
   * @param {String} v 传入需要校验的值
   * @return {Boolean} 返回true或false
   */
  isUndef(v) {
    return v === undefined || v === null;
  },

  /**
   * 是否已定义
   * @param {String} v 传入需要校验的值
   * @return {Boolean} 返回true或false
   */
  isDef(v) {
    return v !== undefined && v !== null;
  },

  /**
   * 是否已定义
   * @param {String} v 传入需要校验的值
   * @return {Boolean} 返回true或false
   */
  isString(v) {
    return v.constructor == String;
  },

  /**
   * 是否已定义
   * @param {Number} v 传入需要校验的值
   * @return {Boolean} 返回true或false
   */
  isNumber(v) {
    return v.constructor == Number;
  },

  /**
   * 是否已定义
   * @param {Boolean} v 传入需要校验的值
   * @return {Boolean} 返回true或false
   */
  isBoolean(v) {
    return v.constructor == true;
  },

  /**
   * 是否已定义
   * @param {Function} v 传入需要校验的值
   * @return {Boolean} 返回true或false
   */
  isFunc(v) {
    return v.constructor == Function;
  },

  /**
   * 是否Array
   * @param {Array} v 传入需要校验的值
   * @return {Boolean} 返回true或false
   */
  isArray(v) {
    return Array.isArray(v);
  },

  // 是否为false - https://www.cnblogs.com/cisum/p/12072873.html
  isTrue(any) {
    let match = ['undefined', 'null', 'NaN', 'false', false, 0, undefined, NaN, ''];
    return match.indexOf(any) > -1 ? false : true;
  },


  /**
   * 是否存在空格
   * @param {Object} obj 传入需要校验的值
   * @return {Boolean} 返回true或false
   */
  isSpaceObject(obj) {
    return Object.keys(obj).length > 0 ? true : false;
  },

  /**
   * 是否存在空格
   * @param {String} str 传入需要校验的值
   * @return {Boolean} 返回true或false
   */
  isSpace(str) {
    return /\s/.test(str);
  },
  /**
   * 是否为符号
   * @param {Symbol} symbol 传入需要校验的值
   * @return {Boolean} 返回true或false
   */
  isSymbol(v) {
    return typeof v === 'symbol';
  },
  /**
   * [获取当前经纬度]
   * const map = await this.$map.latlng();
   * @return {Object}=>{lat:xx,lng:xx}
   */
  latlng: () => {
    return new Promise((resolve, reject) => {
      wx.getLocation({
        type: 'gcj02',
        success: res => {
          resolve({
            lat: res.latitude,
            lng: res.longitude
          });
        },
        fail: err => {
          reject(err);
        }
      });
    });
  },
  /**
   * [传入腾讯地图密钥以获取当前地理位置信息]
   * const map = await this.$map.location({lat:'xx',lng:'xx',key:'xxxx-xxxx'});
   *
   *
   * gcj02不支持国外腾讯地图
   *
   * @return {Object}
   */
  location: ({
               lat,
               lng,
               key
             }) => {
    return new Promise((resolve, reject) => {
      wx.request({
        url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${lat},${lng}&key=${key}`,
        method: 'GET',
        success: res => {
          if (res.data.status == 0) {
            resolve(res.data.result);
          } else {
            reject(res.data.message);
            wx.showModal({
              title: '这里出错了 ~ ',
              content: `${JSON.stringify(res.data)}`,
              showCancel: false
            });
          }
        }
      });
    });
  },


  /*随机数范围*/
  random(min, max) {
    if (arguments.length === 2) {
      return Math.floor(min + Math.random() * ((max + 1) - min))
    } else {
      return null;
    }

  },
  moneyFormat(number, decimals, dec_point, thousands_sep) {
    /*
     * 参数说明：
     * number：要格式化的数字
     * decimals：保留几位小数
     * dec_point：小数点符号
     * thousands_sep：千分位符号
     * */
    number = (number + '').replace(/[^0-9+-Ee.]/g, '');
    var n = !isFinite(+number) ? 0 : +number,
      prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
      sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
      dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
      s = '',
      toFixedFix = function(n, prec) {
        var k = Math.pow(10, prec);
        return '' + Math.floor(n * k) / k;
      };
    s = (prec ? toFixedFix(n, prec) : '' + Math.floor(n)).split('.');
    var re = /(-?\d+)(\d{3})/;
    // console.log(s)
    while (re.test(s[0])) {
      s[0] = s[0].replace(re, "$1" + sep + "$2");
    }
    if ((s[1] || '').length < prec) {
      s[1] = s[1] || '';
      s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
  },
  /**
   * 数值转字符串
   * @param {Number}
   * @return {String}
   */
  numStr(v) {
    return v.toString();
  },
  /**
   * 数值转字符串
   * @param {Number} num 当前数字
   * @param {Number} total 当前总数
   * @return {String} 返回百分比
   */
  numPer(num, total) {
    num = parseFloat(num);
    total = parseFloat(total);
    if (isNaN(num) || isNaN(total)) {
      return "-";
    }
    return total <= 0 ? "0%" : (Math.round(num / total * 10000) / 100.00) + "%";
  },
  /**
   * 取小数位
   * @param {String,Number}
   * @return {String}
   */
  numDigit(digit, num = 2) {
    return Number(digit).toFixed(num);
  },
  /**
   * 取最小数
   * @param {String,Number}
   * @return {String}
   */
  numMin(v1, v2) {
    return Math.min(Number(v1), Number(v2));
  },
  /**
   * 取最大数
   * @param {String,Number}
   * @return {String}
   */
  numMax(v1, v2) {
    return Math.max(Number(v1), Number(v2));
  },
  /**
   * 返回数的绝对值
   * @param {String,Number}
   * @return {String}
   */
  numAbs(v) {
    return Math.abs(Number(v));
  },
  /**
   * 向上取整
   * @param {String,Number}
   * @return {String}
   */
  numUp(v) {
    return Math.ceil(Number(v));
  },
  /**
   * 向下取整
   * @param {String,Number}
   * @return {String}
   */
  numDown(v) {
    return Math.floor(Number(v));
  },
  /**
   * 去除小数部分
   * @param {String,Number}
   * @return {String}
   */
  numTrunc(v) {
    return Math.trunc(Number(v));
  },
  /**
   * 判断是否为正数/负数/零
   * @param {String,Number}
   * @return {String}
   */
  isSign(v) {
    return Math.sign(Number(v));
  },
  /**
   * 判断是否为整数
   * @param {String,Number}
   * @return {String}
   */
  isInt(v) {
    return Number.isInteger(Number(v));
  },

  /**
   * [URL参数拼接]
   * @param [url,obj]
   * @return {String}
   */

  createURL({
              url,
              obj
            }) {
    return new Promise((resolve, reject) => {
      let props = "";
      for (let p in obj) {
        if (obj[p])
          props += "&" + p + "=" + obj[p];
      }
      resolve(`${url}?${props.substr(1)}`);
    });
  },



  /**
   * 将对象解析成url字符串
   * @param  {Object} obj 参数对象
   * @param  {Boolean} unEncodeURI 不使用编码
   * @return {String} 转换之后的url参数
   */

  param(obj = {}, unEncodeURI) {
    let result = [];

    for (let name of Object.keys(obj)) {
      let value = obj[name];

      result.push(name + '=' + (unEncodeURI ? value : encodeURIComponent(value)));
    }

    if (result.length) {
      return '?' + result.join('&');
    } else {
      return '';
    }
  },

  /**
   * 将url字符串解析成对象
   * @param  {String} str 带url参数的地址
   * @param  {Boolean} unDecodeURI 不使用解码
   * @return {Object} 转换之后的url参数
   */

  unparam(str = '', unDecodeURI) {
    let result = {};
    let arr = str.split('&');
    arr.forEach((item, idx) => {
      let param = item.split('='),
        name = param[0],
        value = param[1] || '';
      if (name) {
        result[name] = unDecodeURI ? value : decodeURIComponent(value);
      }
    });

    return result;
  },



  /**
   * 校验手机号
   * @param mobile
   * @returns {boolean}
   */
  checkPhone(mobile) {
    return /^[1][0-9]{10}$/.test(mobile)
  },

  /**
   * 校验纯数字
   * @param num
   * @returns {boolean}
   */
  checkNum(num) {
    return /^[0-9]+$/.test(num)
  },

  /**
   * 校验用户名：1-20位字符，首字符为字母
   * @param str
   * @returns {RegExp}
   */
  checkUserName(str) {
    return /^[a-zA-Z]{1,20}$/.test(str)
  },

  /**
   * 校验密码：6-20位，数字、字母、下划线
   * @param str
   * @returns {boolean}
   */
  checkPwd(str) {
    return /^(\\w){6,20}$/.test(str)
  },

  /**
   * 校验正整数 + 0
   * @param num
   * @returns {boolean}
   */
  checkPositiveInteger(num) {
    return /^[0-9]*[1-9][0-9]*$/.test(num)
  },

  /**
   * 校验字符串是否为数字
   * @param str
   * @returns {boolean}
   */
  checkNumber(str) {
    let regPos = /^\d+(\.\d+)?$/; //非负浮点数
    let regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; //负浮点数
    if (regPos.test(str) || regNeg.test(str)) {
      return true;
    } else {
      return false;
    }
  },
  /**
   * 校验字符串是否为电子邮箱
   * @param str
   * @returns {boolean}
   */
  checkEmail(str) {
    return /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
      .test(str);
  },
  /**
   * 小于10补零
   * @param {String,Number} number 传入的数值
   * @return {String} 返回字符串
   */
  toDigit(any) {
    return any.toString().replace(/^(\d)$/, `0$1`);
  },
  /**
   * 类型判断
   * @param {Any} value 任意需要判断的参数
   * @return {String} 返回的类型
   */
  type(v) {
    return Object.prototype.toString.call(v).split(' ')[1].substr(0, Object.prototype.toString.call(v).split(
      ' ')[1].length -
      1);
  },


  /**
   * 取小数位
   * @param {String,Number}
   * @return {String}
   */

  digit(digit, num = 2) {
    return Number(digit).toFixed(num);
  },
  /**
   * 获取点击元素携带值
   * @param {Object} e 点击对象
   * @param {String} elename 点击所获取的具体值
   * @return {Object,String} getElement 返回对象或者字符串
   */

  ele(e, elename) {
    return elename ? e.currentTarget.dataset[elename] : e.currentTarget.dataset;
  },
  // 获取任意区间随机数
  random(min, max) {
    return min + Math.floor(Math.random() * (max - min + 1));
  },
  /**
   * [匹配item是否在数组]
   * @param [m:延迟时间]
   * @return [none]
   */
  delay(m = 3, success) {
    setTimeout(() => {
      success()
    }, m * 1e3);
  },
  /**
   * [去除所有空格]
   * @param [str:字符串]
   * @return str
   */
  spaceRemove(str) {
    return str.replace(/\s+/g, '');
  },



  /**
   * [sleep睡眠时间]
   * @return {Boolean}
   */
  sleep(numberMillis) {
    let now = new Date();
    let exitTime = now.getTime() + numberMillis;
    while (true) {
      now = new Date();
      if (now.getTime() > exitTime)
        return;
    }
  },

  /**
   * @param {Function}
   * @return {String} time 返回程序所用时间
   */
  timeConsum(callback) {
    console.time('timeTaken');
    const r = callback();
    console.timeEnd('timeTaken');
    return r;
  }
}
